﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;

namespace System.Net.Shared
{
    public static class HttpRequestHelper
    {
        static internal HttpStatusCode _lastResultCode {get; private set;}
        static internal string _lastErrorReason { get; private set; }
        static internal bool LargeResultReturning = false;
        public static async Task<string> simpleHttpPost(string url, string postData = "", string authHeader = "")
        {
            _lastResultCode = HttpStatusCode.Unused;
            _lastErrorReason = "";
            var uri = new Uri(url);

            HttpWebRequest client = HttpWebRequest.CreateHttp(uri);
            client.Method = "POST";
            if (!String.IsNullOrEmpty(authHeader))
            {
                client.Headers["Authorization"] = authHeader;
            }
            if(!String.IsNullOrEmpty(postData))
            {
                var contentStream = await client.GetRequestStreamAsync();
                using(var writer = new StreamWriter(contentStream))
                {
                    writer.Write(postData);
                }
            }
            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)(await client.GetResponseAsync());
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }
            catch (Exception ex2)
            {
                var t = ex2;
            }
            _lastResultCode = response.StatusCode;

            if ((int)_lastResultCode < 400)
            {
                using (var strm = (new StreamReader( response.GetResponseStream()))){
                    return await strm.ReadToEndAsync();
                }
            }

            _lastErrorReason = response.StatusDescription;
            return "";
        }

        public static async Task<string> simpleHttpGet(string url, string authHeader = "")
        {
            _lastResultCode = HttpStatusCode.Unused;
            _lastErrorReason = "";
            var uri = new Uri(url);

            HttpWebRequest client = HttpWebRequest.CreateHttp(uri);
            client.Method = "GET";
            if (!String.IsNullOrEmpty(authHeader))
            {
                client.Headers["Authorization"] = authHeader;
            }

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)(await client.GetResponseAsync());
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }
            if (response.Headers["WWW-Authenticate"] != null)
                Debug.WriteLine("WWW-Authenticate problem: {0}", response.Headers["WWW-Authenticate"]);

            _lastResultCode = response.StatusCode;

            if ((int)_lastResultCode < 400)
            {
                using (var strm = (new StreamReader(response.GetResponseStream())))
                {
                    return await strm.ReadToEndAsync();
                }
            }

            _lastErrorReason = response.StatusDescription;
            return "";
        }

        public static async Task<string> simpleHttpPut(string url, byte[] fileContents, string authHeader = "")
        {

            _lastResultCode = HttpStatusCode.Unused;
            _lastErrorReason = "";
            var uri = new Uri(url);

            HttpWebRequest client = HttpWebRequest.CreateHttp(uri);
            client.Method = "PUT";
            if (!String.IsNullOrEmpty(authHeader))
            {
                client.Headers["Authorization"] = authHeader;
            }

            using (var reqStream = (await client.GetRequestStreamAsync()))
            {
                await reqStream.WriteAsync(fileContents, 0, fileContents.Length);
            }

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)(await client.GetResponseAsync());
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }

            _lastResultCode = response.StatusCode;

            if ((int)_lastResultCode < 400)
            {
                using (var strm = (new StreamReader(response.GetResponseStream())))
                {
                    return await strm.ReadToEndAsync();
                }
            }

            _lastErrorReason = response.StatusDescription;
            return "";
        }

        public static async Task<string> simpleHttpPut(string url, Stream fileStream, string authHeader = "")
        {

            _lastResultCode = HttpStatusCode.Unused;
            _lastErrorReason = "";
            var uri = new Uri(url);

            HttpWebRequest client = HttpWebRequest.CreateHttp(uri);
            client.Method = "PUT";
            if (!String.IsNullOrEmpty(authHeader))
            {
                client.Headers["Authorization"] = authHeader;
            }

            using (var reqStream = (await client.GetRequestStreamAsync()))
            {
                await fileStream.CopyToAsync(reqStream);
            }

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)(await client.GetResponseAsync());
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }

            _lastResultCode = response.StatusCode;

            if ((int)_lastResultCode < 400)
            {
                using (var strm = (new StreamReader(response.GetResponseStream())))
                {
                    return await strm.ReadToEndAsync();
                }
            }

            _lastErrorReason = response.StatusDescription;
            return "";
        }

        public static async Task<Stream> simpleHttpGetStream(string url, string authHeader = "")
        {

            _lastResultCode = HttpStatusCode.Unused;
            _lastErrorReason = "";
            var uri = new Uri(url);

            HttpWebRequest client = HttpWebRequest.CreateHttp(uri);
            client.Method = "GET";
            if (!String.IsNullOrEmpty(authHeader))
            {
                client.Headers["Authorization"] = authHeader;
            }

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)(await client.GetResponseAsync());
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }

            _lastResultCode = response.StatusCode;

            if ((int)_lastResultCode < 400)
            {
                return response.GetResponseStream();
            }

            _lastErrorReason = response.StatusDescription;
            return null;
        }
        public static async Task<byte[]> simpleHttpGetBuffer(string url, string authHeader = "")
        {

            _lastResultCode = HttpStatusCode.Unused;
            _lastErrorReason = "";
            var uri = new Uri(url);

            HttpWebRequest client = HttpWebRequest.CreateHttp(uri);
            client.Method = "GET";
            if (!String.IsNullOrEmpty(authHeader))
            {
                client.Headers["Authorization"] = authHeader;
            }

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)(await client.GetResponseAsync());
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }

            _lastResultCode = response.StatusCode;

            if ((int)_lastResultCode < 400)
            {
                var buffer = new byte[response.ContentLength];
                using (var strm = response.GetResponseStream()) {
                    await strm.ReadAsync(buffer, 0, buffer.Length);
                }
                return buffer;
            }

            _lastErrorReason = response.StatusDescription;
            return null;
        }

        internal static async Task<bool> simpleHttpGetSavedToStream(string url, Func<Stream> getStreamFunc, string authHeader = "")
        {
            _lastResultCode = HttpStatusCode.Unused;
            _lastErrorReason = "";
            var uri = new Uri(url);

            HttpWebRequest client = HttpWebRequest.CreateHttp(uri);
            client.Method = "GET";
            if (!String.IsNullOrEmpty(authHeader))
            {
                client.Headers["Authorization"] = authHeader;
            }

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)(await client.GetResponseAsync());
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }


            _lastResultCode = response.StatusCode;

            if ((int)_lastResultCode < 400)
            {
                try
                {
                    using (var strm =  response.GetResponseStream())
                    {
                        if (getStreamFunc != null)
                        {
                            using (var outStrm = getStreamFunc())
                            {
                                await strm.CopyToAsync(outStrm);
                            }
                        }
                    }
                }
                catch (Exception ex) 
                {
                    _lastResultCode = HttpStatusCode.NotAcceptable;
                    _lastErrorReason = ex.Message;
                    return false; 
                }
                return true;
            }

            _lastErrorReason = response.StatusDescription;
            return false;            
        }
    }
}
